<template>
  <div class="home">
    <div class="ai-generate-form">
      <el-form :model="form" label-width="auto">
        <!-- 批量上传区域 -->
        <el-form-item label="批量上传图片">
          <el-upload ref="uploadRef" action="#" multiple :auto-upload="false" :limit="100" :on-exceed="handleExceed"
            :on-change="handleFileChange" :file-list="fileList" list-type="picture-card">
            <el-icon>
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>

        <!-- 模特选择 -->
        <el-form-item label="选择模特">
          <el-select v-model="form.modelId" filterable placeholder="请选择模特">
            <el-option v-for="model in modelList" :key="model.id" :label="model.name" :value="model.id">
              <div style="display: flex; align-items: center">
                <el-avatar :size="20" :src="model.image" />
                <span style="margin-left: 10px">{{ model.name }}</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <!-- 在el-form中添加背景选择字段 -->
        <el-form-item label="背景设置">
          <!-- 模板背景选择 -->
          <el-select v-model="form.locationId" filterable placeholder="选择场景">
            <el-option v-for="bg in backgroundOptions" :key="bg.id" :label="bg.name" :value="bg.id">
              <div style="display: flex; align-items: center">
                <el-avatar :size="20" :src="bg.image" />
                <span style="margin-left: 10px">{{ bg.name }}</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>

        <!-- 描述输入区域 -->
        <el-form-item label="描述">
          <el-input type="textarea" placeholder="您希望呈现的画面..." v-model="form.description" rows="4" />
        </el-form-item>

        <!-- 模特姿势AI自由度 -->
        <el-form-item label="模特姿势AI自由度">
          <div class="slider-container">
            <el-slider v-model="form.poseFreedom" :min="0" :max="100" :marks="{ 0: '0%', 50: '50%', 100: '100%' }"
              @change="handlePoseFreedomChange" />
          </div>
        </el-form-item>

        <!-- 皮肤细节 -->
        <el-form-item label="皮肤细节">
          <el-radio-group v-model="form.skinDetail" @change="handleSkinDetailChange">
            <el-radio label="原生">原生</el-radio>
            <el-radio label="质感">质感</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 构图 -->
        <el-form-item label="构图">
          <el-radio-group v-model="form.composition" @change="handleCompositionChange">
            <el-radio label="参考场景">参考场景</el-radio>
            <el-radio label="参考原图">参考原图</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 底部按钮 -->
        <div class="btn-group">
          <el-button type="primary" @click="handleSubmit" :loading="isProcessing">
            {{ isProcessing ? `处理中 (${processedCount}/${fileList.length})` : '开始批量处理' }}
          </el-button>
          <el-button @click="handleCancel" v-if="isProcessing">取消</el-button>
        </div>
      </el-form>
    </div>

    <!-- 结果展示区域 -->
    <div class="resultList">
      <div class="result" v-for="(item, index) in resultList" :key="index">
        <el-image :src="item.src" :preview-src-list="resultList.map(r => r.src)" />
        <div class="result-meta">
          <span>原图: {{ item.originalName }}</span>
          <el-button size="small" @click="downloadImage(item.src, item.originalName)">
            下载
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElNotification } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'

// 上传组件引用
const uploadRef = ref(null)
// 添加背景相关数据
const backgroundOptions = ref([]);

// 表单数据
const form = reactive({
  modelId: null,
  description: '',
  negativeDescription: '',
  poseFreedom: 0,
  skinDetail: '原生',
  composition: '参考原图',
  resultType: '图片',
  generateCount: '1',
  locationId: null,
})

// 模特列表
const modelList = ref([])
const fileList = ref([])
const resultList = ref([])
const isProcessing = ref(false)
const processedCount = ref(0)
const cancelRequested = ref(false)

// 获取模特列表
onMounted(async () => {
  try {
    const response = await fetchAgentInfo();
    console.log('response',response);
    
    modelList.value = response.fashionModels;
    backgroundOptions.value = response.locations;
    
  } catch (error) {
    ElMessage.error('获取模特列表失败: ' + error.message)
  }
})

const fetchAgentInfo = async () => {
  try {
    const url = 'https://openapi.weshop.com/openapi/v1/agent/info?agentName=aimodel&agentVersion=v1.0'
    const apiKey = 'gBLoiveusjoTgEH16DBo5iUQFnOdAwcH'

    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': apiKey
      }
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    const data = await response.json()
    return data.data

  } catch (error) {
    console.error('Error fetching agent info:', error)
    throw error
  }
}

// 文件超出限制
const handleExceed = () => {
  ElMessage.warning('最多只能上传100张图片')
}

// 文件变化
const handleFileChange = (file, files) => {
  fileList.value = files
}

// 提交处理 - 整合后的统一接口调用
const handleSubmit = async () => {
  if (!form.modelId) {
    ElMessage.warning('请选择模特');
    return;
  }

  if (fileList.value.length === 0) {
    ElMessage.warning('请上传至少一张图片');
    return;
  }

  isProcessing.value = true;
  cancelRequested.value = false;
  processedCount.value = 0;
  resultList.value = [];

  // 创建AbortController用于取消请求
  const controller = new AbortController();

  try {
    // 使用for...of按顺序处理，避免并发问题
    for (const [index, file] of fileList.value.entries()) {
      if (cancelRequested.value) break;

      try {
        // 显示当前处理进度
        processedCount.value = index + 1;

        // 设置5分钟超时
        const timeoutPromise = new Promise((_, reject) =>
          setTimeout(() => reject(new Error('请求超时（5分钟）')), 5 * 60 * 1000)
        );

        // 执行上传和处理
        const uploadPromise = processImageFile(
          file.raw,
          form.modelId,
          {
            description: form.description,
            poseFreedom: form.poseFreedom,
            skinDetail: form.skinDetail,
            composition: form.composition,
            generateCount: form.generateCount,
            fileName: file.name,
            locationId: form.locationId
          },
          controller.signal // 传入AbortSignal
        );

        const result = await Promise.race([uploadPromise, timeoutPromise]);

        // 实时渲染结果
        if (result?.imageUrl) {
          resultList.value.push({
            src: result.imageUrl,
            originalName: file.name
          });

          // 使用requestAnimationFrame优化渲染性能
          await new Promise(resolve => requestAnimationFrame(resolve));
        }

        ElNotification.success({
          title: '处理成功',
          message: `${file.name} 已处理完成 (${index + 1}/${fileList.value.length})`,
          position: 'bottom-right'
        });
      } catch (error) {
        console.error(`处理 ${file.name} 失败:`, error);
        ElNotification.error({
          title: '处理失败',
          message: `${file.name} 处理失败: ${error.message}`,
          position: 'bottom-right'
        });

        // 可选：是否继续处理后续文件
        // if (shouldAbortOnError) break;
      }
    }
  } finally {
    isProcessing.value = false;
  }
};

const processImageFile = async (file, modelId, options, signal) => {
  const formData = new FormData();
  formData.append('file', file)
  formData.append('modelId', modelId)
  // 添加背景参数
  formData.append('locationId', options.locationId)
  formData.append('description', options.description)
  formData.append('poseFreedom', options.poseFreedom)
  formData.append('skinDetail', options.skinDetail)
  formData.append('composition', options.composition)
  formData.append('generateCount', options.generateCount)
  formData.append('fileName', options.fileName)

  const response = await fetch('http://localhost:3000/api/process-image', {
    method: 'POST',
    body: formData,
    signal, // 支持请求取消
    headers: {
      'Timeout': `${5 * 60 * 1000}` // 自定义超时头
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.message || '处理失败');
  }

  return response.json();
};

// 取消处理
const handleCancel = () => {
  cancelRequested.value = true
  ElMessage.info('正在取消处理，请稍候...')
}

// 下载图片
const downloadImage = (url, name) => {
  const link = document.createElement('a')
  link.href = url
  link.download = `result_${name}`
  link.style.display = 'none'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}
</script>


<style scoped>
.home {
  width: 100%;
  height: 100%;
  display: flex;
  padding: 20px;
  box-sizing: border-box;
}

.ai-generate-form {
  width: 400px;
  padding-right: 20px;
  overflow-y: auto;
}

.resultList {
  flex: 1;
  height: 460px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
  padding: 0 20px;
  overflow-y: auto;
}

.result {
  position: relative;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.result-meta {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 8px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.slider-container {
  width: 80%;
}

.btn-group {
  text-align: right;
  margin-top: 20px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .home {
    flex-direction: column;
  }

  .ai-generate-form {
    width: 100%;
    padding-right: 0;
    margin-bottom: 20px;
  }

  .resultList {
    padding: 0;
  }
}
</style>